/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 artifact.cpp

	$Header: /heroes4/artifact.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "artifact.h"

#include "artifact_effect.h"
#include "artifact_effect_visitor.h"
#include "artifact_properties.h"
#include "artifact_slot.h"
#include "artifact_type.h"
#include "streambuf_operators.h"

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
t_artifact::t_artifact()
{
	m_icon = k_artifact_none;
}

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
/*
bool t_artifact::accept( t_artifact_effect_visitor& visitor ) const
{
	if (m_effects.empty())
		return false;

	int i=0;
	int size  =  m_effects.size();

	visitor.set_artifact( this );

	while(i<size)
	{
		if (m_effects[i]->accept( visitor ))
			return true;

		i++;
	}

	return false;
}
*/

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
static int const k_current_version = 10000;

bool t_artifact::read( std::streambuf& buffer )
{
	int i;
	int size;
	int version = get<t_int16>( buffer );

	if (version < k_current_version)
	{
		m_icon = t_artifact_type( version );
		version = 0;
	}
	else
	{
		if (version > k_current_version)
			return false;
		m_icon  = t_artifact_type( get<t_int16>(buffer) );
	}

	if (m_icon == k_artifact_none)
		return true;

	if (m_icon >= k_artifact_type_count)
		return false;

	m_level = t_artifact_level( get<t_uint8>(buffer) );
	size    = get<t_uint16>( buffer );

	m_effects.clear();
	m_effects.reserve( size );
	for (i = 0; i < size; i++)
	{
		t_artifact_effect_type type = t_artifact_effect_type( get<t_uint8>( buffer ) );
		t_artifact_effect_ptr  effect = create_effect( type );

		if (!effect->read( buffer ))
			return false;
		m_effects.push_back( effect );
	}
	read_string16( buffer, m_help_text );
	read_string16( buffer, m_name );
	if (version >= 10000)
		read_string16( buffer, m_name_with_article );
	else
		m_name_with_article = m_name;
	read_string16( buffer, m_pickup_text );
	return true;
}

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
bool t_artifact::write( std::streambuf& buffer ) const
{
	int i;

	put<t_int16>( buffer, k_current_version );
	put<t_int16>( buffer, m_icon );
	if (m_icon == k_artifact_none)
		return true;
	put<t_uint8>( buffer, m_level );
	put<t_uint16>( buffer, m_effects.size() );
	for (i = 0; i < m_effects.size(); i++)
	{
		put<t_uint8>( buffer, m_effects[i]->get_effect() );
		if (!m_effects[i]->write( buffer ))
			return false;
	}
	write_string16( buffer, m_help_text );
	write_string16( buffer, m_name );
	write_string16( buffer, m_name_with_article );
	write_string16( buffer, m_pickup_text );
	return true;
}

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
bool t_artifact::has_effect( t_artifact_effect_type effect ) const
{
	int i;

	for (i = 0; i < m_effects.size(); i++)
	{
		if (m_effects[i]->get_effect() == effect)
			return true;
	}
	return false;
}

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
t_artifact_slot t_artifact::get_slot() const
{
	if (m_icon == k_artifact_none)
		return k_artifact_slot_none;
	return ::get_slot( m_icon );
}

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
bool t_artifact::is_potion() const
{
	return get_slot() == k_artifact_slot_potion;
}
